<template>
  <div class="pf-flow-prop-multi-instance" id="js-properties-panel-custom">
    <pf-form :config="formConfig" :model="formData" @changeEvent="formChange"></pf-form>
  </div>
</template>

<script lang="ts">
import { defineComponent, nextTick, onMounted, ref, Ref, toRefs, watch } from 'vue';
import { FormModel } from 'pf-component';
import { buildMultiInstance } from '@/views/page-config/flow/custom-properties/form-data';
import { CamundaTaskName, modeler, TaskName } from '@/views/page-config/flow/flow-modeler';

export default defineComponent({
  name: 'ElementMultiInstance',
  props: ['businessObject'],
  setup(props) {
    const bo: Ref = toRefs(props).businessObject;
    const formConfig: Ref<FormModel> = ref(buildMultiInstance());
    const formData: Ref = ref({ _async: [] } as any);
    let multiLoopInstance: any = null;

    const formChange = (newV: any, prop: string) => {
      if (prop === 'collection' || prop === 'elementVariable') {
        updateLoopBase();
      } else if (prop === 'completionCondition') {
        updateLoopCondition(newV);
      } else if (prop === 'timeCycle') {
        updateLoopTimeCycle(newV);
      } else if (prop === 'loopCardinality') {
        updateLoopCardinality(newV);
      } else if (prop === 'loopCharacteristics') {
        if (newV === '-1' || newV === 'StandardLoop') {
          formConfig.value.fields.forEach(f => {
            if (f.prop !== 'loopCharacteristics') {
              f.hidden = true;
            }
          });
        } else {
          formConfig.value.fields.forEach(f => {
            if (f.prop !== 'loopCharacteristics') {
              f.hidden = false;
            }
          });
        }
        changeLoopCharacteristicsType(newV);
      } else if (prop === '_async') {
        const newV = formData.value._async || [];
        if (!showExclusive(newV)) {
          const o = formConfig.value.fields
            .find(f => f.prop === '_async')
            ?.options?.find((o: any) => o.key === 'exclusive');
          if (o) {
            o.disabled = true;
          }
          formData.value._async = formData.value._async?.filter((v: string) => v !== 'exclusive');
        } else {
          const o = formConfig.value.fields
            .find(f => f.prop === '_async')
            ?.options?.find((o: any) => o.key === 'exclusive');
          if (o) {
            o.disabled = false;
          }
        }
        updateLoopAsync(newV);
      }
    };
    const resetElementLoop = (businessObject: any) => {
      if (!businessObject.loopCharacteristics) {
        formData.value = { loopCharacteristics: '-1', _async: [] };
        return;
      }
      if (businessObject.loopCharacteristics.$type === TaskName.standardLoop) {
        formData.value = { loopCharacteristics: 'StandardLoop', _async: [] };
        return;
      }
      const formValue: any = {
        completionCondition: '',
        loopCardinality: '',
        extensionElements: [],
        loopCharacteristics: '',
        _async: []
      };
      if (businessObject.loopCharacteristics.isSequential) {
        formValue.loopCharacteristics = 'SequentialMultiInstance';
      } else {
        formValue.loopCharacteristics = 'ParallelMultiInstance';
      }
      if (businessObject.loopCharacteristics.asyncAfter) {
        formValue._async.push('asyncAfter');
      }
      if (businessObject.loopCharacteristics.asyncBefore) {
        formValue._async.push('asyncBefore');
      }
      if (businessObject.loopCharacteristics.exclusive) {
        formValue._async.push('exclusive');
      }
      // 合并配置
      formData.value = {
        ...formValue,
        ...businessObject.loopCharacteristics,
        completionCondition: businessObject.loopCharacteristics?.completionCondition?.body ?? '',
        loopCardinality: businessObject.loopCharacteristics?.loopCardinality?.body ?? ''
      };
      // 保留当前元素 businessObject 上的 loopCharacteristics 实例
      multiLoopInstance = modeler.getActiveElement().businessObject.loopCharacteristics;
      // 更新表单
      if (
        businessObject.loopCharacteristics.extensionElements &&
        businessObject.loopCharacteristics.extensionElements.values &&
        businessObject.loopCharacteristics.extensionElements.values.length
      ) {
        formData.value.timeCycle =
          businessObject.loopCharacteristics.extensionElements.values[0].body;
      }
    };
    const changeLoopCharacteristicsType = (type: string) => {
      // 取消多实例配置
      if (type === '-1') {
        modeler.updateActiveElement({ loopCharacteristics: null });
        return;
      }
      // 配置循环
      if (type === 'StandardLoop') {
        const loopCharacteristicsObject = modeler.getModdle().create(TaskName.standardLoop);
        modeler.updateActiveElement({
          loopCharacteristics: loopCharacteristicsObject
        });
        multiLoopInstance = null;
        return;
      }
      // 时序
      if (type === 'SequentialMultiInstance') {
        multiLoopInstance = modeler.getModdle().create(TaskName.multiLoop, {
          isSequential: true
        });
      } else {
        multiLoopInstance = modeler.getModdle().create(TaskName.multiLoop);
      }
      modeler.updateActiveElement({
        loopCharacteristics: multiLoopInstance
      });
    };
    // 循环基数
    const updateLoopCardinality = (cardinality: any) => {
      let loopCardinality = null;
      if (cardinality && cardinality.length) {
        loopCardinality = modeler.getModdle().create(TaskName.formalExpr, { body: cardinality });
      }
      modeler.updateActiveModdleProperties(multiLoopInstance, {
        loopCardinality
      });
    };
    // 完成条件
    const updateLoopCondition = (condition: any) => {
      let completionCondition = null;
      if (condition && condition.length) {
        completionCondition = modeler.getModdle().create(TaskName.formalExpr, { body: condition });
      }
      modeler.updateActiveModdleProperties(multiLoopInstance, {
        completionCondition
      });
    };
    // 重试周期
    const updateLoopTimeCycle = (timeCycle: any) => {
      const extensionElements = modeler.getModdle().create(TaskName.extensionEl, {
        values: [
          modeler.getModdle().create(CamundaTaskName.failedRetryTime, {
            body: timeCycle
          })
        ]
      });
      modeler.updateActiveModdleProperties(multiLoopInstance, {
        extensionElements
      });
    };
    // 直接更新的基础信息
    const updateLoopBase = () => {
      modeler.updateActiveModdleProperties(multiLoopInstance, {
        collection: formData.value.collection || null,
        elementVariable: formData.value.elementVariable || null
      });
    };
    // 各异步状态
    const showExclusive = (newV: string[]): boolean => {
      return (
        newV && newV.length > 0 && (newV.includes('asyncBefore') || newV.includes('asyncAfter'))
      );
    };
    const updateLoopAsync = (newV: string[]) => {
      let asyncAttr;
      if (!showExclusive(newV)) {
        asyncAttr = {
          asyncBefore: false,
          asyncAfter: false,
          exclusive: false,
          extensionElements: null
        };
      } else {
        asyncAttr = {
          asyncBefore: newV && newV.includes('asyncBefore'),
          asyncAfter: newV && newV.includes('asyncAfter'),
          exclusive: newV && newV.includes('exclusive')
        };
      }
      modeler.updateActiveModdleProperties(multiLoopInstance, asyncAttr);
    };
    onMounted(() => {
      console.log('element multi instance mounted ........', bo.value);
    });
    watch(
      bo,
      val => {
        nextTick(() => {
          console.log('element multi instance reset ........', bo.value);
          resetElementLoop(val);
          console.log('element multi instance reset ........over', multiLoopInstance);
        });
      },
      { immediate: true }
    );
    return {
      formConfig,
      formData,
      formChange
    };
  }
});
</script>
<style scoped lang="scss">
.#{$prefix} {
}
</style>
